package com.csx.data.orm.jpa.base.controller;
import com.csx.data.orm.jpa.base.entity.User;
import com.csx.data.orm.jpa.base.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequestMapping("/jpa")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    // ************************************ 查询数据 ******************************************************
    // 查询1: 根据 单个唯一键属性 查询获取 唯一数据. 1  —>  1
    @GetMapping("/findById")
    public User findById(@RequestParam Long id) {
        return userService.findById(id);
    }

    @GetMapping("/findAllByIds")
    public List<User> findAllByIds(@RequestParam List<Long> ids) {
        return userService.findAllByIds(ids);
    }

    // 查询2: 根据 单个非唯一属性 查询获取 多条数据. 1  —>  n
    @GetMapping("/findByFirstNameIgnoreCase")
    public List<User> findByFirstNameIgnoreCase(@RequestParam String firstName) {
        return userService.findByFirstNameIgnoreCase(firstName);
    }

    // 查询: 根据 单个非唯一属性列表 查询获取多条数据 1 -> n
    @GetMapping("/findByFirstNameIn")
    public List<User> findByFirstNameIn(@RequestParam List<String> firstNames) {
        return userService.findByFirstNameIn(firstNames);
    }


    // 查询3: 根据 多个非唯一属性 查询获取 唯一数据. n  —>  1
    @GetMapping("/findByFirstNameAndLastName")
    public User findByFirstNameAndLastName(@RequestParam String firstName, @RequestParam String lastName) {
        return userService.findByFirstNameAndLastName(firstName, lastName);
    }

    // 查询4: 根据 多个非唯一属性 查询获取 多条数据. n  —>  n
    @GetMapping("/findByAgeAndCity")
    public List<User> findByAgeAndCity(@RequestParam int age, @RequestParam String city) {
        return userService.findByAgeAndCity(age, city);
    }

    // 查询5: 查询并排序
    @GetMapping("/findByFirstNameOrderByLastNameAsc")
    public List<User> findByFirstNameOrderByLastNameAsc(@RequestParam String firstName) {
        return userService.findByFirstNameOrderByLastNameAsc(firstName);
    }
    @GetMapping("/findByFirstNameSortedByFirstNameAsc")
    public List<User> findByFirstNameSortedByFirstNameAsc(@RequestParam String firstName) {
        return userService.findByFirstNameSortedByFirstNameAsc(firstName);
    }

    // 查询6: 分页查询
    // 注意: page 需要从0开始
    @GetMapping("/findAllWithPage")
    public Page<User> findAllWithPage(@RequestParam(required = false, defaultValue = "0") int page, @RequestParam(required = false, defaultValue = "10") int size) {
        return userService.findAllWithPage(page, size);
    }

    // 查询7: 模糊查询
    @GetMapping("/findByFirstNameContainingIgnoreCase")
    public List<User> findByFirstNameContainingIgnoreCase(String keyword) {
        return userService.findByFirstNameContainingIgnoreCase(keyword);
    }

    // 查询8: 通过 Specification 实现 多条件灵活查询(条件存在则拼接上去,否则不拼接该条件)
    // 注: age这种 整数类型的使用 Integer 而不是 int,否则可能会出现无法处理空值的情况，如果要使用需要赋默认值0
    @GetMapping("/findAll")
    public List<User> findAll(@RequestParam(required = false) String firstName, @RequestParam(required = false) String lastName, @RequestParam(required = false) Integer age, @RequestParam(required = false) String city) {
        return userService.findAll(firstName, lastName, age, city);
    }


    // ************************************ 新增/修改数据 ******************************************************
    // 新增/修改1: 新增/修改 单条数据
    @PostMapping("/save")
    public User save(@RequestBody User user) {
        return userService.save(user);
    }

    /**
     * 注意: 这个saveAll() 方法看似是 批量处理，其实底层还是循环调用了 save() 方法,
     * 具体代码可以查看{@link SimpleJpaRepository#saveAll(Iterable)}
     *
     * 因此, 这是一个 <b>假批量 ！！！</b>
     */
    // 新增/修改2: 新增/修改 多条数据
    @PostMapping("/saveAll")
    public List<User> saveAll(@RequestBody List<User> users) {
        return userService.saveAll(users);
    }

    // 新增/修改3: 新增/修改 多条数据 (真批量)
    public List<User> saveAllInBatch(@RequestBody List<User> users) {
        return userService.saveAllInBatch(users);
    }

    // ************************************ 删除数据 ******************************************************
    // 删除1: 根据 主键 删除 单条数据
    @PostMapping("/deleteById")
    public String deleteById(@RequestParam Long id) {
        userService.deleteById(id);
        return "deleteById success";
    }

    // 删除2: 根据 主键列表 删除 多条数据
    @PostMapping("/deleteAllById")
    public String deleteAllById(@RequestBody List<Long> ids) {
        userService.deleteAllById(ids);
        return "deleteAllById success";
    }

    // 删除3: 根据 非主键 删除 多条数据
    @PostMapping("/deleteByLastName")
    public String deleteByLastName(@RequestParam String lastName) {
        userService.deleteByLastName(lastName);
        return "deleteByLastName success";
    }

    // 删除4: 根据 实体 删除数据
    @PostMapping("/delete")
    public String delete(@RequestBody User user) {
        userService.delete(user);
        return "delete success";
    }

    // 删除5: 根据 实体列表 删除数据
    @PostMapping("/deleteAll")
    public String deleteAll(@RequestBody List<User> users) {
        userService.deleteAll(users);
        return "deleteAll success";
    }

    @GetMapping("/getUser")
    public User getUser(@RequestParam Long id) {
        return userService.getUser(id);
    }

}
